package com.iotcomm.client;

import com.iotcomm.protocol.Message;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.VBox;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URL;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.ResourceBundle;

/**
 * 客户端界面控制器
 */
public class ClientController implements Initializable {
    private static final Logger logger = LoggerFactory.getLogger(ClientController.class);
    
    // 连接面板
    @FXML private VBox connectionPanel;
    @FXML private TextField usernameField;
    @FXML private TextField hostField;
    @FXML private TextField portField;
    @FXML private Button connectButton;
    
    // 聊天面板
    @FXML private VBox chatPanel;
    @FXML private Label connectionStatusLabel;
    @FXML private Button disconnectButton;
    @FXML private ListView<String> userListView;
    @FXML private TabPane chatTabPane;
    @FXML private TextArea messageInput;
    @FXML private Button sendButton;
    @FXML private Button broadcastButton;
    
    private ChatClient chatClient;
    private ObservableList<String> userList = FXCollections.observableArrayList();
    private String currentChatUser = "广播"; // 当前聊天对象
    
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        // 初始化界面组件
        initializeComponents();
        
        // 初始化聊天客户端
        initializeChatClient();
    }
    
    /**
     * 初始化界面组件
     */
    private void initializeComponents() {
        // 设置默认值
        usernameField.setText("User" + System.currentTimeMillis() % 1000);
        hostField.setText("localhost");
        portField.setText("8888");
        
        // 初始化界面状态
        connectionPanel.setVisible(true);
        chatPanel.setVisible(false);
        
        // 初始化用户列表
        userListView.setItems(userList);
        userListView.getSelectionModel().selectedItemProperty().addListener((obs, oldVal, newVal) -> {
            if (newVal != null && !newVal.equals(currentChatUser)) {
                switchChatTab(newVal);
            }
        });
        
        // 初始化消息输入框
        messageInput.setOnKeyPressed(this::handleMessageInputKeyPressed);
        messageInput.setWrapText(true);
        
        // 创建广播聊天标签页
        createBroadcastTab();
    }
    
    /**
     * 初始化聊天客户端
     */
    private void initializeChatClient() {
        chatClient = new ChatClient();
        
        // 设置回调函数
        chatClient.setConnectionStatusCallback(this::updateConnectionStatus);
        chatClient.setMessageReceivedCallback(this::handleMessageReceived);
        chatClient.setUserListUpdateCallback(this::updateUserList);
        chatClient.setErrorCallback(this::showError);
    }
    
    /**
     * 连接到服务器
     */
    @FXML
    private void connectToServer() {
        try {
            String username = usernameField.getText().trim();
            String host = hostField.getText().trim();
            int port = Integer.parseInt(portField.getText().trim());
            
            // 验证输入
            if (username.isEmpty()) {
                showAlert("错误", "请输入用户名");
                return;
            }
            
            if (host.isEmpty()) {
                showAlert("错误", "请输入服务器地址");
                return;
            }
            
            if (port < 1 || port > 65535) {
                showAlert("错误", "端口号必须在1-65535之间");
                return;
            }
            
            // 禁用连接按钮
            connectButton.setDisable(true);
            connectButton.setText("连接中...");
            
            // 在新线程中连接
            new Thread(() -> {
                chatClient.connect(host, port, username);
            }).start();
            
        } catch (NumberFormatException e) {
            showAlert("错误", "请输入有效的端口号");
        } catch (Exception e) {
            logger.error("连接服务器时发生错误", e);
            showAlert("错误", "连接失败: " + e.getMessage());
            resetConnectButton();
        }
    }
    
    /**
     * 断开连接
     */
    @FXML
    private void disconnectFromServer() {
        if (chatClient != null) {
            new Thread(() -> {
                chatClient.disconnect();
            }).start();
        }
    }
    
    /**
     * 发送消息
     */
    @FXML
    private void sendMessage() {
        String content = messageInput.getText().trim();
        if (content.isEmpty()) {
            return;
        }
        
        if (chatClient == null || !chatClient.isConnected()) {
            showError("未连接到服务器");
            return;
        }
        
        try {
            if ("广播".equals(currentChatUser)) {
                // 发送广播消息并立即在本地显示
                chatClient.sendBroadcastMessage(content);
                
                // 在界面上显示发送的广播消息
                Message sentMessage = Message.createBroadcast(chatClient.getUsername(), content);
                displayMessage("广播", sentMessage, true);
            } else {
                // 发送私聊消息
                chatClient.sendPrivateMessage(currentChatUser, content);
                
                // 在界面上显示发送的消息
                Message sentMessage = Message.createPrivateChat(chatClient.getUsername(), currentChatUser, content);
                displayMessage(currentChatUser, sentMessage, true);
            }
            
            // 清空输入框
            messageInput.clear();
            
        } catch (Exception e) {
            logger.error("发送消息失败", e);
            showError("发送消息失败: " + e.getMessage());
        }
    }
    
    /**
     * 发送广播消息
     */
    @FXML
    private void sendBroadcastMessage() {
        // 切换到广播标签页
        switchChatTab("广播");
        userListView.getSelectionModel().clearSelection();
    }
    
    /**
     * 处理消息输入框按键事件
     */
    private void handleMessageInputKeyPressed(KeyEvent event) {
        if (event.getCode() == KeyCode.ENTER) {
            if (event.isShiftDown()) {
                // Shift+Enter 换行
                messageInput.appendText("\n");
            } else {
                // Enter 发送消息
                event.consume();
                sendMessage();
            }
        }
    }
    
    /**
     * 更新连接状态
     */
    private void updateConnectionStatus(String status) {
        Platform.runLater(() -> {
            // 如果已登录，显示用户名和状态
            if ("已登录".equals(status) && chatClient != null) {
                connectionStatusLabel.setText("用户: " + chatClient.getUsername() + " | 状态: " + status);
            } else {
                connectionStatusLabel.setText("状态: " + status);
            }
            
            if ("已登录".equals(status)) {
                // 切换到聊天界面
                connectionPanel.setVisible(false);
                chatPanel.setVisible(true);
            } else if (status.contains("断开") || status.contains("失败") || status.contains("错误")) {
                // 切换回连接界面
                chatPanel.setVisible(false);
                connectionPanel.setVisible(true);
                resetConnectButton();
                
                // 清空用户列表和聊天标签页
                userList.clear();
                clearChatTabs();
            }
        });
    }
    
    /**
     * 处理接收到的消息
     */
    private void handleMessageReceived(Message message) {
        Platform.runLater(() -> {
            switch (message.getMessageType()) {
                case Message.PRIVATE_CHAT:
                    // 显示接收到的私聊消息（服务器不再回显发送者的消息）
                    String chatUser = message.getSender();
                    displayMessage(chatUser, message, false);
                    
                    // 如果当前没有选中聊天对象，自动切换到发送者
                    if (currentChatUser == null || "广播".equals(currentChatUser)) {
                        switchChatTab(chatUser);
                    }
                    break;
                case Message.BROADCAST:
                    // 如果是自己发送的广播消息，直接丢弃（因为发送时已经在本地显示了）
                    if (message.getSender().equals(chatClient.getUsername())) {
                        logger.debug("丢弃自己发送的广播消息: {}", message.getContent());
                        break;
                    }
                    // 显示其他用户发送的广播消息
                    displayMessage("广播", message, false);
                    break;
                default:
                    logger.debug("收到其他类型消息: {}", message.getMessageType());
            }
        });
    }
    
    /**
     * 更新用户列表
     */
    private void updateUserList(List<String> users) {
        Platform.runLater(() -> {
            userList.clear();
            
            // 过滤掉自己
            users.stream()
                    .filter(user -> !user.equals(chatClient.getUsername()))
                    .forEach(userList::add);
            
            logger.debug("用户列表更新: {} 个用户", userList.size());
        });
    }
    
    /**
     * 显示错误信息
     */
    private void showError(String error) {
        Platform.runLater(() -> {
            showAlert("错误", error);
        });
    }
    
    /**
     * 在聊天区域显示消息
     */
    private void displayMessage(String chatUser, Message message, boolean isSent) {
        // 确保有对应的聊天标签页
        Tab chatTab = findOrCreateChatTab(chatUser);
        TextArea chatArea = (TextArea) chatTab.getContent();
        
        // 格式化消息
        String timestamp = message.getTimestamp();
        String sender = isSent ? "我" : message.getSender();
        String formattedMessage;
        
        if ("广播".equals(chatUser)) {
            formattedMessage = String.format("[%s] %s: %s%n", timestamp, sender, message.getContent());
        } else {
            formattedMessage = String.format("[%s] %s: %s%n", timestamp, sender, message.getContent());
        }
        
        chatArea.appendText(formattedMessage);
        
        // 自动滚动到底部
        chatArea.setScrollTop(Double.MAX_VALUE);
    }
    
    /**
     * 查找或创建聊天标签页
     */
    private Tab findOrCreateChatTab(String chatUser) {
        // 查找现有标签页
        for (Tab tab : chatTabPane.getTabs()) {
            if (chatUser.equals(tab.getText())) {
                return tab;
            }
        }
        
        // 创建新标签页
        Tab newTab = new Tab(chatUser);
        TextArea chatArea = new TextArea();
        chatArea.setEditable(false);
        chatArea.setWrapText(true);
        chatArea.setStyle("-fx-font-family: 'Microsoft YaHei', 'SimSun', sans-serif; -fx-font-size: 12px;");
        
        newTab.setContent(chatArea);
        chatTabPane.getTabs().add(newTab);
        

        
        return newTab;
    }
    
    /**
     * 创建广播聊天标签页
     */
    private void createBroadcastTab() {
        Tab broadcastTab = new Tab("广播");
        TextArea chatArea = new TextArea();
        chatArea.setEditable(false);
        chatArea.setWrapText(true);
        chatArea.setStyle("-fx-font-family: 'Microsoft YaHei', 'SimSun', sans-serif; -fx-font-size: 12px;");
        
        broadcastTab.setContent(chatArea);
        broadcastTab.setClosable(false); // 广播标签页不可关闭
        chatTabPane.getTabs().add(broadcastTab);
        
        // 默认选中广播标签页
        chatTabPane.getSelectionModel().select(broadcastTab);
    }
    
    /**
     * 切换聊天标签页
     */
    private void switchChatTab(String chatUser) {
        currentChatUser = chatUser;
        
        // 查找或创建标签页
        Tab chatTab = findOrCreateChatTab(chatUser);
        
        // 选中标签页
        chatTabPane.getSelectionModel().select(chatTab);
        
        // 更新用户列表选择
        if (!"广播".equals(chatUser)) {
            userListView.getSelectionModel().select(chatUser);
        }
        
        logger.debug("切换到聊天对象: {}", chatUser);
    }
    

    
    /**
     * 清空聊天标签页
     */
    private void clearChatTabs() {
        chatTabPane.getTabs().clear();
        createBroadcastTab();
        currentChatUser = "广播";
    }
    
    /**
     * 重置连接按钮
     */
    private void resetConnectButton() {
        connectButton.setDisable(false);
        connectButton.setText("连接");
    }
    
    /**
     * 显示警告对话框
     */
    private void showAlert(String title, String message) {
        Alert alert = new Alert(Alert.AlertType.ERROR);
        alert.setTitle(title);
        alert.setHeaderText(null);
        alert.setContentText(message);
        alert.showAndWait();
    }
    
    /**
     * 关闭应用程序时的清理工作
     */
    public void shutdown() {
        if (chatClient != null) {
            chatClient.disconnect();
        }
    }
}